package com.ruoyi.qiuyue.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.qiuyue.common.MusicConstat;
import com.ruoyi.qiuyue.domain.MusicFavorite;
import com.ruoyi.qiuyue.domain.MusicSong;
import com.ruoyi.qiuyue.domain.MusicUser;
import com.ruoyi.qiuyue.mapper.MusicSongMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.qiuyue.mapper.MusicLoveMapper;
import com.ruoyi.qiuyue.domain.MusicLove;
import com.ruoyi.qiuyue.service.IMusicLoveService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户收藏Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-05-28
 */
@Service
public class MusicLoveServiceImpl implements IMusicLoveService 
{
    @Autowired
    private MusicLoveMapper musicLoveMapper;
    @Autowired
    private MusicSongMapper musicSongMapper;

    /**
     * 查询用户收藏
     * 
     * @param id 用户收藏主键
     * @return 用户收藏
     */
    @Override
    public MusicLove selectMusicLoveById(Long id)
    {
        return musicLoveMapper.selectMusicLoveById(id);
    }

    /**
     * 查询用户收藏信息
     * @param userId
     * @return
     * @throws JsonProcessingException
     */
    @Override
    public List<MusicSong> getMusicLoveByUserId(Long userId,int pageNum,int pageSize) throws JsonProcessingException {
        MusicLove musicLove = musicLoveMapper.selectMusicLoveByUserId(userId);
        if (musicLove == null) {
            musicLove = createFavorite(userId);
            return new ArrayList<>();
        }
        List<MusicFavorite> favoriteParse = musicLove.getFavoriteParse();
        List<Long> musicIds = favoriteParse.stream().map(MusicFavorite::getMusicId).collect(Collectors.toList());
        if (musicIds.size() == 0) {
            return new ArrayList<>();
        }
        // 简易分页查询 起始位置
        int begin = pageNum*pageSize;
        // 结束位置
        int end = begin+pageSize-1;
        if (end > musicIds.size()) {
            end = musicIds.size();
        }
        musicIds.subList(begin,end);
        List<MusicSong> musicSongs = musicSongMapper.selectMusicSongByIds(musicIds);
        return musicSongs;
    }


    /**
     * 用户添加收藏
     * @param musicUser
     * @param id 用户收藏主键
     * @return
     * @throws JsonProcessingException
     */
    @Override
    public boolean addMusicLoveByUserAndMusicId(MusicUser musicUser, Long musicId) throws JsonProcessingException {
        // 解析歌曲json
        MusicLove musicLove = musicLoveMapper.selectMusicLoveByUserId(musicUser.getId());
        if (musicLove == null){
            musicLove = createFavorite(musicUser.getId());
        }
        List<MusicFavorite> favoriteParse = musicLove.getFavoriteParse();

        // 检查歌曲是否存在
        // 存在歌曲
        int searchIndex = binarySearchByFavoriteId(favoriteParse, musicId);
        if (searchIndex != MusicConstat.SONG_IS_EMPTY_NUMBER) {
            return true;
        }
        // 不存在歌曲
        MusicSong musicSong = musicSongMapper.selectMusicSongById(musicId);
        if (musicSong == null) {
            throw new RuntimeException(MusicConstat.SONG_IS_EMPTY);
        }

        favoriteParse.add(new MusicFavorite(musicId,new Date()));
        musicLove.setFavoriteParse(favoriteParse);
        musicLoveMapper.updateMusicLove(musicLove);
        return true;
    }

    /**
     * 查询用户收藏列表
     * 
     * @param musicLove 用户收藏
     * @return 用户收藏
     */
    @Override
    public List<MusicLove> selectMusicLoveList(MusicLove musicLove)
    {
        return musicLoveMapper.selectMusicLoveList(musicLove);
    }

    /**
     * 新增用户收藏
     * 
     * @param musicLove 用户收藏
     * @return 结果
     */
    @Override
    public int insertMusicLove(MusicLove musicLove)
    {
        return musicLoveMapper.insertMusicLove(musicLove);
    }

    /**
     * 修改用户收藏
     * 
     * @param musicLove 用户收藏
     * @return 结果
     */
    @Override
    public int updateMusicLove(MusicLove musicLove)
    {
        return musicLoveMapper.updateMusicLove(musicLove);
    }

    /**
     * 批量删除用户收藏
     * 
     * @param ids 需要删除的用户收藏主键
     * @return 结果
     */
    @Override
    public int deleteMusicLoveByIds(Long[] ids)
    {
        return musicLoveMapper.deleteMusicLoveByIds(ids);
    }

    /**
     * 删除用户收藏信息
     * 
     * @param id 用户收藏主键
     * @return 结果
     */
    @Override
    public int deleteMusicLoveById(Long id)
    {
        return musicLoveMapper.deleteMusicLoveById(id);
    }

    /**
     * 删除用户歌曲
     * @param user
     * @param id
     * @return
     */
    @Override
    public boolean deleteMusicLoveByUserAndMusicId(MusicUser user, Long id) throws JsonProcessingException {
        // 解析歌曲json
        MusicLove musicLove = musicLoveMapper.selectMusicLoveByUserId(user.getId());
        if (musicLove == null){
            musicLove = createFavorite(user.getId());
        }
        List<MusicFavorite> favoriteParse = musicLove.getFavoriteParse();

        // 检查歌曲是否存在
        // 不存在歌曲
        int searchIndex = binarySearchByFavoriteId(favoriteParse, id);
        if (searchIndex == MusicConstat.SONG_IS_EMPTY_NUMBER) {
            return true;
        }
        favoriteParse.remove(searchIndex);
        musicLove.setFavoriteParse(favoriteParse);
        musicLoveMapper.updateMusicLove(musicLove);
        return true;
    }

    // 查找元素返回下标 不存在返回-1
    public int binarySearchByFavoriteId(List<MusicFavorite> data,Long favoriteId){
        int left = 0;
        int right = data.size()-1;
        while (left <= right)
        {
            int mid = (left + right) / 2;
            Long tempMId = data.get(mid).getMusicId();
            if ( tempMId == favoriteId)
                return mid;
            else if (data.get(mid).getMusicId() > favoriteId)
                right = mid - 1;
            else if (data.get(mid).getMusicId() < favoriteId)
                left = mid + 1;
        }
        return MusicConstat.SONG_IS_EMPTY_NUMBER;
    }


    /**
     * 创建收藏
     * @param userId
     * @return
     * @throws JsonProcessingException
     */
    private MusicLove createFavorite(Long userId) throws JsonProcessingException {
        musicLoveMapper.selectMusicLoveByUserId(userId);
        MusicLove newUserFavorite = new MusicLove();
        newUserFavorite.setUserId(userId);
        newUserFavorite.setFavoriteParse(new ArrayList<MusicFavorite>());
        musicLoveMapper.insertMusicLove(newUserFavorite);
        return newUserFavorite;
    }
}
